package com.inspectortime.webapp.util;

import java.beans.PropertyEditorSupport;
import java.text.DecimalFormat;

import org.springframework.util.NumberUtils;

/**
 * Enhances Spring's editor by allowing alphanumeric synonyms for zero
 * 
 * @author mKvalsvik
 * 
 */
public class FlexibleNumberPropertyEditor extends PropertyEditorSupport {

	private DecimalFormat decimalFormat;
	private Class numberClass;
	private String[] zeroSynonyms;

	public void setDecimalFormat(DecimalFormat decimalFormat) {
		this.decimalFormat = decimalFormat;
	}

	public void setNumberClass(Class numberClass) {
		this.numberClass = numberClass;
	}

	public void setZeroSynonyms(String[] zeroSynonyms) {
		this.zeroSynonyms = zeroSynonyms;
	}

	public FlexibleNumberPropertyEditor() {
		this("###,###,##0.00", Integer.class);
	}

	public FlexibleNumberPropertyEditor(String decimalFormatStr,
			Class numberClass) {
		this(decimalFormatStr, numberClass, new String[] { "" });
	};

	public FlexibleNumberPropertyEditor(String decimalFormatStr,
			Class numberClass, String[] zeroSynonyms) {
		this.decimalFormat = new DecimalFormat(decimalFormatStr);
		this.numberClass = numberClass;
		this.zeroSynonyms = zeroSynonyms;
	};

	private boolean isZeroSynonym(String text) {
		boolean zero = false;
		String trimmedText = text.trim();
		for (int i = 0; i < this.zeroSynonyms.length; i++) {
			if (this.zeroSynonyms[i].equals(trimmedText)) {
				zero = true;
			}
		}
		return zero;
	}

	public void setAsText(String text)
			throws java.lang.IllegalArgumentException {
		if (this.isZeroSynonym(text)) {
			setValue(NumberUtils.convertNumberToTargetClass(0, this.numberClass));
		} else {
			
			// trim and take off starting $-sign if any
			String trimmedText = text.trim();
			if (trimmedText.startsWith("$")) {
				trimmedText = trimmedText.substring(1);
			}
			setValue(NumberUtils.parseNumber(trimmedText, this.numberClass,
					this.decimalFormat));
		}
	}
	
	public String getAsText() {
		Object value = getValue();
		if (value == null) {
			return "";
		}
		if (this.decimalFormat != null) {
			// Use NumberFormat for rendering value.
			return this.decimalFormat.format(value);
		}
		else {
			// Use toString method for rendering value.
			return value.toString();
		}
	}

}
